package com.chukun.gateway.config.nacos;

import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.chukun.gateway.common.rule.Rule;
import com.chukun.gateway.config.api.ConfigCenter;
import com.chukun.gateway.config.api.RulesChangeListener;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * @author chukun
 * @version 1.0.0
 * @description 配置变更处理器，基于nacos实现
 * @createTime 2023/11/26 22:16
 */
@Slf4j
public class NacosConfigCenter implements ConfigCenter {

    private static final String DATA_ID = "api-gateway";

    private static final String NAME_SPACE="gateway";

    private String serverAddress;

    private String env;

    private ConfigService configService;

    @Override
    public void init(String serverAddress, String env) {
        this.serverAddress = serverAddress;
        this.env = env;

        try {
            Properties properties = new Properties();
            properties.put(PropertyKeyConst.SERVER_ADDR, serverAddress);
            properties.put(PropertyKeyConst.NAMESPACE, NAME_SPACE);
            configService = NacosFactory.createConfigService(properties);
        } catch (NacosException e) {
            log.error("NacosConfigCenter.init.error ", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void subscribeRulesChange(RulesChangeListener listener) {
        try {
            //初始化通知
            String config = configService.getConfig(DATA_ID, env, 5000);
            //{"rules":[{}, {}]}
            log.info("NacosConfigCenter.subscribeRulesChange from nacos execte: {}", config);
            List<Rule> rules = JSON.parseObject(config).getJSONArray("rules").toJavaList(Rule.class);
            listener.onRulesChange(rules);

            //监听变化
            configService.addListener(DATA_ID, env, new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.info("config from nacos: {}", configInfo);
                    List<Rule> rules = JSON.parseObject(configInfo).getJSONArray("rules").toJavaList(Rule.class);
                    listener.onRulesChange(rules);
                }
            });
        } catch (NacosException e) {
            log.info("NacosConfigCenter.subscribeRulesChange from nacos error ", e);
            throw new RuntimeException(e);
        }
    }
}
